/************************************************************************************* 
This file is a part of CrashRpt library.

Copyright (c) 2003, Michael Carruth
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this 
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, 
this list of conditions and the following disclaimer in the documentation 
and/or other materials provided with the distribution.

* Neither the name of the author nor the names of its contributors 
may be used to endorse or promote products derived from this software without 
specific prior written permission.


THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***************************************************************************************/

#pragma once
#include "AssyncNotification.h"
#include "MailMsg.h"
#include "smtpclient.h"
#include "HttpRequestSender.h"
#include "tinyxml.h"
#include "CrashInfoReader.h"

// Action type
enum ActionType  
{
    COLLECT_CRASH_INFO = 0x01, // Crash info should be collected
    COMPRESS_REPORT    = 0x02, // Error report files should be packed into ZIP archive
    RESTART_APP        = 0x04, // Crashed app should be restarted
    SEND_REPORT        = 0x08  // Report should be sent
};

// The class that collects crash report files, packs them 
// into a ZIP archive and sends the error report.
class CErrorReportSender
{
public:

    // Constructor.
    CErrorReportSender();

	// Destructor.
    ~CErrorReportSender();

    // This method performs an action assynchronously.
    BOOL DoWork(int action);

    // Allows to specify file name for exporting error report.
    void SetExportFlag(BOOL bExport, CString sExportFile);

    // Blocks until an assync operation finishes.
    void WaitForCompletion();

    // Returns global status.
    int GetGlobalStatus();

    // Gets local operation status.
    void GetStatus(int& nProgressPct, std::vector<CString>& msg_log);

    // Cancels the assync operation.
    void Cancel();

    // Unblocks waiting worker thread.
    void FeedbackReady(int code);

    // Returns size in bytes of error report files.
    LONG64 GetUncompressedReportSize(ErrorReportInfo& eri);

    // Returns current error report's index.
    int GetCurReport();

    // Sets current error report's index.
    BOOL SetCurReport(int nCurReport);

    // Sets log file name.
    BOOL SetLogFile(LPCTSTR szFileName);

    // Cleans up all temp files and does other finalizing work.
    BOOL Finalize();

private:

    // Runs an operation in assync mode.
    void DoWorkAssync();

    // Worker thread proc.
    static DWORD WINAPI WorkerThread(LPVOID lpParam);  

    // Collects crash report files.
    BOOL CollectCrashFiles();  

    // Calculates MD5 hash for a file.
    int CalcFileMD5Hash(CString sFileName, CString& sMD5Hash);

    // Dumps registry key to the XML file.
    int DumpRegKey(CString sRegKey, CString sDestFile, CString& sErrorMsg);

    // Used internally for dumping a registry key.
    int DumpRegKey(HKEY hKeyParent, CString sSubKey, TiXmlElement* elem);

    // Takes desktop screenshot.
    BOOL TakeDesktopScreenshot();

    // Creates crash dump file.
    BOOL CreateMiniDump();  

    // Creates crash description XML file.
    BOOL CreateCrashDescriptionXML(ErrorReportInfo& eri);
	
    // Adds an element to XML file.
    void AddElemToXML(CString sName, CString sValue, TiXmlNode* root);

    // Minidump callback.
    static BOOL CALLBACK MiniDumpCallback(PVOID CallbackParam, PMINIDUMP_CALLBACK_INPUT CallbackInput,
        PMINIDUMP_CALLBACK_OUTPUT CallbackOutput); 

    // Minidump callback.
    BOOL OnMinidumpProgress(const PMINIDUMP_CALLBACK_INPUT CallbackInput,
        PMINIDUMP_CALLBACK_OUTPUT CallbackOutput);

    // Restarts the application.
    BOOL RestartApp();

    // Packs error report files to ZIP archive.
    BOOL CompressReportFiles(ErrorReportInfo& eri);

    // Unblocks parent process.
    void UnblockParentProcess();

    // Sends error report.
    BOOL SendReport();

    // Sends error report over HTTP.
    BOOL SendOverHTTP();

    // Encodes attachment file with Base-64 encoding.
    int Base64EncodeAttachment(CString sFileName, std::string& sEncodedFileData);

    // Formats Email text.
    CString FormatEmailText();

    // Sends error report over SMTP.
    BOOL SendOverSMTP();

    // Sends error report over Simple MAPI.
    BOOL SendOverSMAPI();

    int m_nGlobalStatus;                // Global status.
    int m_nCurReport;                   // Index of current error report.
    HANDLE m_hThread;                   // Handle to the worker thread.
    int m_SendAttempt;                  // Number of current sending attempt.
    AssyncNotification m_Assync;        // Used for communication with the main thread.
    CEmailMessage m_EmailMsg;           // Email message to send.
    CSmtpClient m_SmtpClient;           // Used to send report over SMTP.
    CHttpRequestSender m_HttpSender;    // Used to send report over HTTP.
    CMailMsg m_MapiSender;              // Used to send report over SMAPI.
    CString m_sZipName;                 // Name of the ZIP archive to send.
    int m_Action;                       // Current action.
    BOOL m_bExport;                     // If TRUE than export should be performed.
    CString m_sExportFileName;          // File name for exporting.
};

// A globally accessible error report sender object.
extern CErrorReportSender g_ErrorReportSender;

